using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.Intrinsics.Arm;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NPOI.HPSF;
using Publicuse.Appication;
using Publicuse.Autofac;
using Publicuse.Cache;
using Publicuse.Entity;
using Publicuse.Entity.AttributeUtil;
using Publicuse.Export;
using Publicuse.Interface;
using Publicuse.Interface.Extend;
using Publicuse.Util;
using Geekeradmin.Authorize;
using Geekeradmin.Common;
using static FreeSql.Internal.GlobalFilter;

namespace Geekeradmin.Controllers
{
  /// <summary>
  /// 用户管理模块
  /// </summary>
  [UserAuthorize("Admin")]
  public class UserController : BaseController
  {
    public UserController(
      IAutofaceInstance autoface,
      IMySqlSugarService mySqlSugar,
      IWebHostEnvironment webHost,
      IOptions<DBConnectionOption> options,
      IBaseServiceExt baseServiceExt
    )
      : base(autoface, mySqlSugar, webHost, options, baseServiceExt) { }

    /// <summary>
    /// 获取当前登录账号相关信息
    /// </summary>
    /// <returns></returns>
    [HttpPost("GetUserInfo"), AllowAnonymous]
    public async Task<JsonResult> GetUserInfo()
    {
      CommonResult result = await UserApplication.GetApplication(container).GetUserInfo();
      return new JsonResult(result);
    }

    /// <summary>
    /// 获取当前登录账号模块菜单权限
    /// </summary>
    /// <param name="routetitle"></param>
    /// <param name="routeurl"></param>
    /// <returns></returns>
    [HttpGet("Gettmpotclam"), AllowAnonymous]
    public async Task<JsonResult> Gettmpotclam(string routetitle, string routeurl)
    {
      CommonResult result = await UserApplication
        .GetApplication(container)
        .Gettmpotclam(routetitle, routeurl);
      return new JsonResult(result);
    }

    /// <summary>
    /// 获取用户角色资源列表信息
    /// </summary>
    /// <param name="Id"></param>
    /// <returns></returns>
    [HttpGet("GetUserRoleResList"), AllowAnonymous]
    public async Task<JsonResult> GetUserRoleResList(string Id)
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .GetUserRoleResList(Id);
      return new JsonResult(result);
    }

    /// <summary>
    /// 检查用户是否首次登录，是则需要修改密码
    /// </summary>
    /// <returns></returns>
    [HttpGet("GetLoginFirst"), AllowAnonymous]
    public async Task<JsonResult> GetLoginFirst()
    {
      CommonResult result = await UserApplication.GetApplication(this.container).GetLoginFirst();
      return new JsonResult(result);
    }

    /// <summary>
    /// 获取用户登录信息
    /// </summary>
    /// <param name="query"></param>
    /// <returns></returns>
    [HttpPost("GetUserLoginInfo"), AllowAnonymous]
    public async Task<JsonResult> GetUserLoginInfo(SigninInfoQuery query)
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .GetUserLoginInfo(query);
      return new JsonResult(result);
    }

    /// <summary>
    /// 获取用户信息列表
    /// </summary>
    /// <param name="query"></param>
    /// <returns></returns>
    ///
    [HttpPost("GetList")]
    public async Task<JsonResult> GetList(User query)
    {
      CommonResult result = await UserApplication.GetApplication(this.container).GetList(query);
      return new JsonResult(result);
    }

    /// <summary>
    /// 获取用户下属信息列表
    /// </summary>
    /// <param name="uId"></param>
    /// <param name="ucode"></param>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <returns></returns>
    [HttpGet("GetListb")]
    public async Task<JsonResult> GetListb(string uId, string ucode, int pageIndex, int pageSize)
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .GetListb(uId, ucode, pageIndex, pageSize);
      return new JsonResult(result);
    }

    /// <summary>
    /// 获取用户角色列表
    /// </summary>
    /// <param name="uCode"></param>
    /// <param name="rName"></param>
    /// <param name="type"></param>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <returns></returns>
    [HttpGet("GetListg")]
    public async Task<JsonResult> GetListg(
      string uCode,
      string rName,
      int type,
      int pageIndex,
      int pageSize
    )
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .GetListg(uCode, rName, type, pageIndex, pageSize);
      return new JsonResult(result);
    }

    /// <summary>
    /// 获取用户角色资源列表
    /// </summary>
    /// <param name="uCode"></param>
    /// <param name="rName"></param>
    /// <param name="resName"></param>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <returns></returns>
    [HttpGet("GetListc")]
    public async Task<JsonResult> GetListc(
      string uCode,
      string rName,
      string resName,
      int pageIndex,
      int pageSize
    )
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .GetListc(uCode, rName, resName, pageIndex, pageSize);
      return new JsonResult(result);
    }

    /// <summary>
    /// 获取角色资源列表
    /// </summary>
    /// <param name="rName"></param>
    /// <param name="resName"></param>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <returns></returns>
    [HttpGet("GetListd")]
    public async Task<JsonResult> GetListd(
      string rName,
      string resName,
      int pageIndex,
      int pageSize
    )
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .GetListd(rName, resName, pageIndex, pageSize);
      return new JsonResult(result);
    }

    /// <summary>
    /// 获取用户详细信息
    /// </summary>
    /// <param name="Id"></param>
    /// <returns></returns>
    [HttpGet("GetListe")]
    public async Task<JsonResult> GetDetail(int Id)
    {
      CommonResult result = await UserApplication.GetApplication(this.container).GetDetail(Id);
      return new JsonResult(result);
    }

    /// <summary>
    /// 解除用户绑定相关信息
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    [HttpPost("Unbinduserrole"), AllowAnonymous]
    public async Task<JsonResult> Unbinduserrole(Unbinddata data)
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .Unbinduserrole(data);
      return new JsonResult(result);
    }

    /// <summary>
    /// Des加密
    /// </summary>
    /// <param name="pwd"></param>
    /// <returns></returns>
    [HttpGet("GetDESEncryption"), AllowAnonymous]
    public async Task<JsonResult> GetDESEncryption(string pwd)
    {
      return await Task.Factory.StartNew(() =>
      {
        CommonResult result = new CommonResult();
        result.data = EnDecryptionUtil.DESEncryption(pwd);
        return new JsonResult(result);
      });
    }

    /// <summary>
    /// 检查用户账号是否存在
    /// </summary>
    /// <param name="uCode"></param>
    /// <param name="loginUserCode"></param>
    /// <param name="Id"></param>
    /// <returns></returns>
    [HttpGet("CheckUserCode"), AllowAnonymous]
    public async Task<JsonResult> CheckUserCode(string uCode, string loginUserCode, string Id = "")
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .CheckUserCode(uCode, loginUserCode, Id);
      return new JsonResult(result);
    }

    /// <summary>
    /// 检查用户手机号是否存在
    /// </summary>
    /// <param name="mobile"></param>
    /// <param name="loginUserCode"></param>
    /// <param name="Id"></param>
    /// <returns></returns>
    [HttpGet("CheckUserMobile"), AllowAnonymous]
    public async Task<JsonResult> CheckUserMobile(
      string mobile,
      string loginUserCode,
      string Id = ""
    )
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .CheckUserMobile(mobile, loginUserCode, Id);
      return new JsonResult(result);
    }

    /// <summary>
    /// 保存用户下属信息
    /// </summary>
    /// <param name="uId"></param>
    /// <param name="uCodes"></param>
    /// <param name="loginUserCode"></param>
    /// <returns></returns>
    [HttpGet("SaveUserOrgb"), AllowAnonymous]
    public async Task<JsonResult> SaveUserOrgb(string uId, string uCodes, string loginUserCode)
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .SaveUserOrgb(uId, uCodes, loginUserCode);
      return new JsonResult(result);
    }

    /// <summary>
    /// 新增修改用户信息
    /// </summary>
    /// <param name="info"></param>
    /// <returns></returns>
    [HttpPost("AddOrUpdate")]
    public async Task<JsonResult> AddOrUpdate(User info)
    {
      CommonResult result = await UserApplication.GetApplication(this.container).AddOrUpdate(info);
      return new JsonResult(result);
    }

    /// <summary>
    /// 新增修改用户信息
    /// </summary>
    /// <param name="info"></param>
    /// <returns></returns>
    [HttpPost("Personalse"), AllowAnonymous]
    public async Task<JsonResult> Personalse(User info)
    {
      CommonResult result = await UserApplication.GetApplication(this.container).AddOrUpdate(info);
      return new JsonResult(result);
    }

    /// <summary>
    /// 修改用户登录密码
    /// </summary>
    /// <param name="userPwd"></param>
    /// <returns></returns>
    [HttpPost("UpdatePwd"), AllowAnonymous]
    public async Task<JsonResult> UpdatePwd(UserPwd userPwd)
    {
      CommonResult result = await UserApplication.GetApplication(this.container).UpdatePwd(userPwd);
      return new JsonResult(result);
    }

    /// <summary>
    /// 判断服务器是否升级重启
    /// </summary>
    /// <returns></returns>
    [HttpGet("TheServerInit"), AllowAnonymous]
    public async Task<JsonResult> TheServerInit()
    {
      CommonResult result = await UserApplication.GetApplication(this.container).TheServerInit();
      return new JsonResult(result);
    }

    /// <summary>
    /// 删除用户信息
    /// </summary>
    /// <param name="Id"></param>
    /// <param name="loginUserCode"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    [HttpGet("Delete")]
    public async Task<JsonResult> Delete(string Id, string loginUserCode, string type = "-9")
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .Delete(Id, loginUserCode, type);
      return new JsonResult(result);
    }

    /// <summary>
    /// 还原用户删除信息
    /// </summary>
    /// <param name="Id"></param>
    /// <param name="loginUserCode"></param>
    /// <returns></returns>
    [HttpGet("Reduction"), AllowAnonymous]
    public async Task<JsonResult> Reduction(string Id, string loginUserCode)
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .Reduction(Id, loginUserCode);
      return new JsonResult(result);
    }

    /// <summary>
    /// 导入数据
    /// </summary>
    /// <returns></returns>
    [HttpPost("ImportExcel")]
    public async Task<JsonResult> ImportExcel()
    {
      string path = this.webHost.WebRootPath;
      var files = Request.Form.Files;
      string loginUserCode = Request.Form["loginUserCode"];
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .ImportExcel(files, path, loginUserCode);
      return new JsonResult(result);
    }

    /// <summary>
    /// 上传用户头像
    /// </summary>
    /// <returns></returns>
    [HttpPost("UploadyHead"), AllowAnonymous]
    public async Task<JsonResult> UploadyHead()
    {
      var path = this.webHost.WebRootPath;
      var files = Request.Form.Files;
      UploadYPhoto model = new UploadYPhoto()
      {
        uid = Request.Form["uid"].ToString(),
        logincode = Request.Form["logincode"].ToString(),
      };
      var result = await this.UploadFile<User>(
        files,
        model.logincode,
        "uploadyhead",
        model,
        this.webHost.WebRootPath,
        BusinessType.user,
        true
      );
      return new JsonResult(result);
    }

    /// <summary>
    /// 保存用户绑定系统模块信息
    /// </summary>
    /// <param name="sid"></param>
    /// <param name="uids"></param>
    /// <param name="loginUserCode"></param>
    /// <returns></returns>
    [HttpGet("SaveUserModule"), AllowAnonymous]
    public async Task<JsonResult> SaveUserModule(string sid, string uids, string loginUserCode)
    {
      return await Task.Factory.StartNew(() =>
      {
        CommonResult result = new CommonResult();
        autoface.DoWork(
          BusinessType.user,
          BusinessActionType.update,
          loginUserCode,
          "保存用户绑定系统模块信息",
          BusinessLogType.writeLogToDataBase,
          (o) =>
          {
            var userTable = TableAtributeUtil.GetTable<User>();
            string msg = string.Empty;
            var sql = string.Empty;
            sql = $"update {userTable} set sysmoduleid={sid} where Id in({uids}) ";
            this.mySqlSugar.ExecuteSql(sql, null, out msg);
            result.msg = msg;
            return result;
          },
          null,
          ref result
        );
        return new JsonResult(result);
      });
    }

    /// <summary>
    /// 保存多个用户绑定系统资源信息
    /// </summary>
    /// <param name="sid"></param>
    /// <param name="uids"></param>
    /// <param name="loginUserCode"></param>
    /// <returns></returns>
    [HttpGet("SaveUserRoleResource"), AllowAnonymous]
    public async Task<JsonResult> SaveUserRoleResource(
      string sid,
      string uids,
      string loginUserCode
    )
    {
      return await Task.Factory.StartNew(() =>
      {
        CommonResult result = new CommonResult();
        autoface.DoWork(
          BusinessType.user,
          BusinessActionType.update,
          loginUserCode,
          "保存多个用户绑定系统资源信息",
          BusinessLogType.writeLogToDataBase,
          (o) =>
          {
            var userTable = TableAtributeUtil.GetTable<User>();
            var userroleTable = TableAtributeUtil.GetTable<UserRole>();
            string msg = string.Empty;
            var sql = string.Empty;
            sql = $"select rids from {userroleTable} where uid in({uids}); ";
            DataTable dataTable = new DataTable();
            dataTable = this.mySqlSugar.GetDataTable(sql, null, out msg);
            if (string.IsNullOrEmpty(msg) && dataTable != null)
            {
              if (dataTable.Rows.Count > 0)
              {
                var newuids = uids.Split(',');
                foreach (DataRow item in dataTable.Rows)
                {
                  var ridsb = item["rids"].ToString();
                  var rids = ridsb.Split(',');
                  var tableName = TableAtributeUtil.GetTable<URPermission>();
                  sql = $"select aids from {tableName} where uId in({uids}) and rId in({ridsb});";
                  DataTable dataTableb = new DataTable();
                  dataTableb = this.mySqlSugar.GetDataTable(sql, null, out msg);
                  if (string.IsNullOrEmpty(msg) && dataTableb != null)
                  {
                    if (dataTableb.Rows.Count > 0)
                    {
                      foreach (DataRow itemb in dataTableb.Rows)
                      {
                        var aids = itemb["aids"].ToString();
                        aids = aids + "," + sid;
                        aids = string.Join(",", aids.Split(',').Distinct());
                        foreach (var rid in rids)
                        {
                          foreach (var uid in newuids)
                          {
                            sql =
                              $"update {tableName} set aids='{aids}' where uId='{uid.GetIntValue()}' and rId='{rid.GetIntValue()}';";
                            this.mySqlSugar.ExecuteSql(sql, null, out msg);
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
            else
            {
              result.code = (int)CodeResult.fail;
              result.msg = msg;
            }
            return result;
          },
          null,
          ref result
        );
        return new JsonResult(result);
      });
    }

    /// <summary>
    /// 获取省市区数据
    /// </summary>
    /// <param name="loginUserCode"></param>
    /// <returns></returns>
    [HttpGet("GetCityData"), AllowAnonymous]
    public async Task<JsonResult> GetCityData(string loginUserCode)
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .GetCityData(loginUserCode);
      return new JsonResult(result);
    }

    /// <summary>
    /// 生成用户信息
    /// </summary>
    /// <param name="saveUserRoles"></param>
    /// <returns></returns>
    [HttpPost("Generateuser"), AllowAnonymous]
    public async Task<JsonResult> Generateuser(SaveUserRole saveUserRoles)
    {
      CommonResult result = await UserApplication
        .GetApplication(this.container)
        .Generateuser(saveUserRoles);
      return new JsonResult(result);
    }

    /// <summary>
    /// 导出数据信息
    /// </summary>
    /// <param name="query"></param>
    /// <returns></returns>
    [HttpGet("ExportData")]
    public async Task<IActionResult> ExportData([FromQuery] User query)
    {
      return await Task.Factory.StartNew<IActionResult>(() =>
      {
        MemoryStream ms = new MemoryStream();
        var exportname = "用户信息统计";
        var filepath = "\\template\\report\\user.xls";

        CommonResult result = new CommonResult();
        var userTable = TableAtributeUtil.GetTable<User>();
        var role = TableAtributeUtil.GetTable<Role>();
        var userrole = TableAtributeUtil.GetTable<UserRole>();
        var LoginAppid = HttpContextExtendBase.GetLoginAppid(query.loginToken);
        query.loginUserCode = HttpContextExtendBase.GetLoginCode(query.loginToken);
        var LoginrName = HttpContextExtendBase.GetLoginrName(query.loginToken);
        var tableName =
          $"(select a.*,r.rids as rId from {userTable} a left join {userrole} r on r.uId=a.Id and r.type=1 )as urp";

        string sql = query.GetQueryString<User>(
          (a) =>
          {
            string rId = string.Empty;
            if (!string.IsNullOrEmpty(query.rName))
            {
              var rolesql = $"select Id from {role} where rName like '%{query.rName}%';";
              var rolelist = this.mySqlSugar.Query<Role>(rolesql, null, out var msg);
              if (string.IsNullOrEmpty(msg) && rolelist != null && rolelist.Count > 0)
              {
                rId = String.Join(",", rolelist.Select(o => o.Id.ToString()).Distinct().ToList());
              }
              else
              {
                rId = "0";
              }
            }
            if (!string.IsNullOrEmpty(rId))
            {
              a += $" and  (FIND_IN_SET('{rId}',rId) or FIND_IN_SET(rId,'{rId}')) ";
            }

            if (
              string.Compare(query.loginUserCode, "ajng", true) != 0
              && string.Compare(LoginAppid, "admin", true) != 0
            )
            {
              var LoginuId = HttpContextExtendBase.GetLoginuId(query.loginToken);
              var sql =
                $"select Id,associateuon,associateuonuser from {userTable} where Id='{LoginuId}' and status = 1 and associateuon = '是';";
              var userlist = this.mySqlSugar.Query<User>(sql, out var msg);
              if (string.IsNullOrEmpty(msg) && userlist != null && userlist.Count > 0)
              {
                var associateuonuser = userlist.FirstOrDefault().associateuonuser;
                if (!string.IsNullOrEmpty(associateuonuser))
                {
                  a +=
                    $" and  (FIND_IN_SET(uCode,'{associateuonuser}') or  uCode='{query.loginUserCode}')) ";
                }
                else
                {
                  a += $" and  (uCode='{query.loginUserCode}') ";
                }
              }
              else
              {
                a += $" and  (uCode='{query.loginUserCode}' ) ";
              }
            }
            else
            {
              if (!string.IsNullOrEmpty(query.uCode))
              {
                a += string.Format(" and uCode like '%{0}%' ", query.uCode);
              }
            }
            if (!string.IsNullOrEmpty(query.Idb))
            {
              a += string.Format(" and Id like '%{0}%' ", query.Idb);
            }

            if (!string.IsNullOrEmpty(query.LoginType))
            {
              a += $" and LoginType='{query.LoginType}' ";
            }
            if (!string.IsNullOrEmpty(query.logintimest))
            {
              a += $" and logintime>='{query.logintimest}' ";
            }
            if (!string.IsNullOrEmpty(query.logintimeet))
            {
              a += $" and logintime<='{query.logintimeet}' ";
            }
            return a;
          }
        );
        if (string.Compare(query.loginUserCode, "ajng", true) != 0)
        {
          sql += " and uCode<>'ajng' ";
        }
        UserQuery userQuery = new UserQuery()
        {
          tableName = tableName,
          sqlWhere = sql,
          sortFile = query.sortFile,
          sortType = query.sortType,
          pageIndex = query.pageIndex,
          pageSize = 100000,
          files = "*"
        };
        long total = 0;
        List<User> list = new List<User>();
        this.mySqlSugar.GetList<User>(userQuery, out var msg, out list, out total);

        if (list != null && list.Count > 0)
        {
          var rolelist = UserAuthorCache.GetRolecache();
          var userrolelist = UserAuthorCache.GetUserRolecache();
          var diclist = UserAuthorCache.GetDictionariescache();
          list.ForEach(o =>
          {
            //o.uPwd = EnDecryptionUtil.AesDecrypt(o.uPwd);
            if (rolelist != null && rolelist.Count > 0)
            {
              if (userrolelist != null && userrolelist.Count > 0)
              {
                var haveuserrole = userrolelist.Where(b => b.uId == o.Id && b.type == 1);
                if (haveuserrole != null && haveuserrole.Count() > 0)
                {
                  var rIds = haveuserrole.FirstOrDefault().rids.Split(',');
                  var haverole = rolelist.Where(o => rIds.Any(b => b == o.Id.ToString()));
                  if (haverole != null && haverole.Count() > 0)
                  {
                    o.rName = String.Join(",", haverole.Select(o => o.rName));
                  }
                }
              }
            }
            if (diclist != null && diclist.Count > 0)
            {
              if (!string.IsNullOrEmpty(o.pca))
              {
                List<string> dicaname = new List<string>();
                foreach (var itemb in o.pca.Split(','))
                {
                  var dica = diclist.Where(o => o.Id == itemb.GetIntValue());
                  if (dica.Count() > 0)
                  {
                    dicaname.Add(dica.FirstOrDefault().dName);
                  }
                }
                if (dicaname.Count > 0)
                {
                  o.pcaremark = String.Join("", dicaname);
                }
              }
            }
          });
        }

        if (string.IsNullOrEmpty(msg) && list != null && list.Count > 0)
        {
          string webRootPath = webHost.WebRootPath;
          string fileName = webRootPath + filepath;
          ms = UserExport.ExportData(
            fileName,
            exportname,
            list,
            this.webHost.WebRootPath,
            out var msgb
          );
          if (string.IsNullOrEmpty(msg) && ms != null)
          {
            return File(ms.ToArray(), "application/ms-excel", exportname + ".xls");
          }
          else
          {
            return File(new byte[] { }, "application/ms-excel", exportname + ".xls");
          }
        }
        else
        {
          return File(new byte[] { }, "application/ms-excel", exportname + ".xls");
        }
      });
    }
  }
}
